package com.ysx.common.utils;

import com.alibaba.fastjson.JSON;
import com.ysx.common.pojo.TokenJsonVo;
import com.ysx.common.pojo.TokenRole;
import com.ysx.common.pojo.UserTokenInfo;
import com.ysx.common.pojo.UserTokenInfoExp;
import io.jsonwebtoken.*;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

public class JwtToutiaoUtil {
    //加密的秘钥
    private static final byte[] key = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY".getBytes();

    //过期时间单位为60s
    public static final int TOKEN_TIME_OUT = 60;


    /**
     * @param userToken 用户令牌的封装对象
     * @return 刷新令牌和访问令牌的封装对象
     */
    public static TokenJsonVo createToken(UserTokenInfo userToken) {
        Instant now = Instant.now().truncatedTo(ChronoUnit.SECONDS);
        //访问令牌过期时间
        ZonedDateTime accessExpire = now.atZone(ZoneId.systemDefault()).plusSeconds(TOKEN_TIME_OUT);
        ZonedDateTime RefreshExpire = now.atZone(ZoneId.systemDefault()).plusSeconds(TOKEN_TIME_OUT * 5);
        //刷新令牌过期时间 两倍
        Date accessDate = Date.from(accessExpire.toInstant());
        Date refreshDate = Date.from(RefreshExpire.toInstant());

        Map<String, Object> tokenMap = JSON.parseObject(JSON.toJSONString(userToken), Map.class);

        //访问令牌
        String accessToken = Jwts.builder()
                .addClaims(tokenMap)
                .signWith(SignatureAlgorithm.HS256, key)
                .setExpiration(accessDate)
                .compact();


        //刷新令牌
        String refreshToken = Jwts.builder()
                .addClaims(tokenMap)
                .signWith(SignatureAlgorithm.HS256, key)
                .setExpiration(refreshDate)
                .compact();

        //生成两个令牌数据
        TokenJsonVo tokenJsonVo = new TokenJsonVo(accessToken, refreshToken);

        return tokenJsonVo;

    }

    public static boolean isValidRole(String token, TokenRole role) {
        UserTokenInfoExp tokenInfoExp = parseJwtUserToken(token);
        return tokenInfoExp.getRole() == role;
    }
    //https://www.coder.work/article/1413231
    //https://www.cnblogs.com/goloving/p/14922929.html

    //解析令牌信息
    public static UserTokenInfoExp parseJwtUserToken(String token) {
        Claims body = null;
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(token);
            body = claimsJws.getBody();
            UserTokenInfoExp tokenInfoExp = JSON.parseObject(JSON.toJSONString(body), UserTokenInfoExp.class);
            return tokenInfoExp;
        } catch (ExpiredJwtException e) {
            //照样获取数据
            e.printStackTrace();
            body = e.getClaims();
            UserTokenInfoExp tokenInfoExp = JSON.parseObject(JSON.toJSONString(body), UserTokenInfoExp.class);
            //这里时间转换有问题 需要重新设置一次
            tokenInfoExp.setExp(body.getExpiration().getTime());
            return tokenInfoExp;
        } catch (MalformedJwtException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        return null;
    }


}
